﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace OpenPasteSpider
{
	/// <summary>
	/// 
	/// </summary>
	public class PublicString
	{
		/// <summary>
		/// data:item:app:{app.id}
		/// </summary>
		public const string CacheItemAppInfo = "data:item:app:{0}";

		/// <summary>
		/// data:item:model:{model.id}
		/// </summary>
		public const string CacheItemModelInfo = "data:item:model:{0}";

		/// <summary>
		/// data:item:service:{service.id}
		/// </summary>
		public const string CacheItemServiceInfo = "data:item:service:{0}";

		/// <summary>
		/// data:item:project:{project.id}
		/// </summary>
		public const string CacheItemProjectInfo = "data:item:project:{0}";

		/// <summary>
		/// data:item:linux:{linux.id}
		/// </summary>
		public const string CacheItemLinuxInfo = "data:item:linux:{0}";

		/// <summary>
		/// data:item:store:{store.id}
		/// </summary>
		public const string CacheItemStoreInfo = "data:item:store:{0}";

		/// <summary>
		/// 图形验证码缓存值
		/// </summary>
		public const string CacheImageHead = "data:cache:image:{0}";

		/// <summary>
		/// data:item:serviceinclude:{service.id}
		/// </summary>
		public const string CacheItemServiceInfoInclude = "data:item:serviceinclude:{0}";

		/// <summary>
		/// RevicerInfoDto.item cache:itemdto:revicer:{revicerinfo.id}
		/// </summary>
		public const string CacheItemRevicer = "cache:itemdto:revicer:{0}";

		/// <summary>
		/// MessageInfoDto.item cache:itemdto:message:{messageinfo.code}
		/// </summary>
		public const string CacheItemMessage = "cache:itemdto:message:{0}";

		/// <summary>
		/// List RevicerInfoList
		/// </summary>
		public const string CacheListRevicer = "cache:list:revicer";

		/// <summary>
		/// 消息接收者 cache:noticer:(code) 5分钟延迟
		/// </summary>
		public const string CacheNoticeReviceHead = "cache:noticer:";

		/// <summary>
		/// 锁定运行机制 project.id service.id plantype model.code appid
		/// </summary>
		public const string CacheLockSpiderRun = "lock:{0}:{1}:{2}:{3}:{4}";

		/// <summary>
		/// 角色包含的样式的缓存 cache:role:list:{0}
		/// </summary>
		public const string CacheGradeInfoHead = "cache:role:list:{0}";

	}

	/// <summary>
	/// 字符串扩展
	/// </summary>
	public static class StringExpand
	{

		/// <summary>
		/// 把字符串拆分成行
		/// </summary>
		/// <param name="text"></param>
		/// <returns></returns>
		public static List<string> SplitByLine(this string text)
		{
			List<string> lines = new List<string>();
			byte[] array = Encoding.UTF8.GetBytes(text);
			using (System.IO.MemoryStream stream = new System.IO.MemoryStream(array))
			{
				using (var sr = new System.IO.StreamReader(stream))
				{
					string line = String.Empty;
					while (!sr.EndOfStream)
					{
						line = sr.ReadLine();
						if (!String.IsNullOrEmpty(line))
						{
							lines.Add(line);
						}

					};
				}
			}
			return lines;
		}

		/// <summary>
		/// Reject The Number Char From String By Regex
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static string RejectNumChar(this string str)
		{
			if (!String.IsNullOrEmpty(str))
			{
				return System.Text.RegularExpressions.Regex.Replace(str, "[0-9]", "");
			}
			else
			{
				return str;
			}
		}

		/// <summary>
		/// 转化成base64
		/// </summary>
		/// <param name="content"></param>
		/// <returns></returns>
		public static string ToBase64Encode(this string content)
		{
			byte[] bytes = Encoding.UTF8.GetBytes(content);
			return Convert.ToBase64String(bytes);
		}


		/// <summary>
		/// 时间转时间戳ms ok
		/// </summary>
		/// <param name="dt"></param>
		/// <returns></returns>
		public static long ToUnixTimeMilliseconds(this DateTime dt)
		{
			return new DateTimeOffset(dt).ToUnixTimeMilliseconds();
		}

		/// <summary>
		/// 时间转时间戳s ok
		/// </summary>
		/// <param name="dt"></param>
		/// <returns></returns>
		public static long ToUnixTimeSeconds(this DateTime dt)
		{
			var dto = new DateTimeOffset(dt);
			return new DateTimeOffset(dt).ToUnixTimeSeconds();
		}

		/// <summary>
		/// 时间转换成Utc时间戳 理论上会减去时区的加成 ok
		/// </summary>
		/// <param name="dt"></param>
		/// <returns></returns>
		public static long ToUtcMilliSeconds(this DateTime dt)
		{
			return new DateTimeOffset(dt).ToUnixTimeMilliseconds() - (long)TimeZoneInfo.Local.BaseUtcOffset.TotalMilliseconds;
		}

		/// <summary>
		/// 时间戳转换成时间 ok
		/// </summary>
		/// <param name="timestamp">timestamp</param>
		/// <returns></returns>
		public static DateTime ToUtcDateFromMilliSecond(this long timestamp)
		{
			var date = TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1), TimeZoneInfo.Local);
			return date.AddMilliseconds(timestamp);
		}

		/// <summary>
		/// 时间戳转换成本地时间 ok
		/// </summary>
		/// <param name="timestamp">timestamp</param>
		/// <returns></returns>
		public static DateTime ToDateTimeFromSecond(this long timestamp)
		{
			var date = TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1), TimeZoneInfo.Local);
			return date.AddSeconds(timestamp).AddHours(TimeZoneInfo.Local.BaseUtcOffset.Hours);
		}

		/// <summary>
		/// 秒数转化成时间 ok
		/// </summary>
		/// <param name="seconds"></param>
		/// <returns></returns>
		public static DateTime ToUtcDateTimeFromSecond(this long seconds)
		{
			var date = TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1), TimeZoneInfo.Local);
			return date.AddSeconds(seconds);
		}

		/// <summary>
		/// 时间戳ms转时间 ok
		/// </summary>
		/// <param name="timestamp">ms</param>
		/// <returns></returns>
		public static DateTime ToDateTimeFromMilliseconds(this long timestamp)
		{

			var date = TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1), TimeZoneInfo.Local);
			return date.AddMilliseconds(timestamp).AddHours(TimeZoneInfo.Local.BaseUtcOffset.Hours);
		}

		/// <summary>
		/// 转化成小写的md5
		/// </summary>
		/// <param name="inputValue"></param>
		/// <returns></returns>
		public static string ToMd5Lower(this string inputValue)
		{

			using (var md5 = MD5.Create())
			{
				var result = md5.ComputeHash(Encoding.UTF8.GetBytes(inputValue));
				var strResult = BitConverter.ToString(result);
				return strResult.Replace("-", "").ToLower();
			}
		}


		/// <summary>
		/// 生成密钥
		/// </summary>
		/// <param name="userid"></param>
		/// <param name="gradecode"></param>
		/// <param name="savehour">密钥过期小时数</param>
		/// <param name="_usertoken">会员密钥</param>
		/// <returns></returns>
		public static string BuildToken(this int userid, string gradecode, int savehour = 12, string _usertoken = "")
		{
			var now = DateTime.Now.AddHours(12).ToUnixTimeSeconds();
			var temptoken = $"{now}_{userid}_{_usertoken}".ToMd5Lower();
			return $"{now}_{userid}_{gradecode}_{temptoken}";
		}

		/// <summary>
		/// 校验密钥
		/// </summary>
		/// <param name="token"></param>
		/// <param name="_usertoken"></param>
		/// <returns></returns>
		public static bool CheckToken(this string token, string _usertoken)
		{
			if (!string.IsNullOrEmpty(token))
			{
				var strs = token.Split("_");
				if (strs.Length == 4)
				{
					//时间校验
					var now = DateTime.Now.ToUnixTimeSeconds();
					long.TryParse(strs[0], out var tokentime);
					if (tokentime < now)
					{
						return false;
					}
					//加密校验
					if (strs[3] == $"{strs[0]}_{strs[1]}_{_usertoken}".ToMd5Lower())
					{
						return true;
					}
				}
			}

			return false;
		}

	}
}
